/*
 *     This file is part of Mobile GPS Logger.
 * 
 *     Mobile GPS Logger is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 * 
 *     Mobile GPS Logger is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License v3 for more details.
 * 
 *     You should have received a copy of the GNU General Public License v3
 *     along with Mobile GPS Logger. If not, see <http://www.gnu.org/licenses/>.
*/


package cx.ath.skyflyer.chart;

import java.util.Enumeration;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author Ahti Legonkov
 */
public class Chart
    extends Canvas {

    public Chart(boolean fullScreen) {

        setFullScreenMode(fullScreen);
        
        Rectangle screenRect = new Rectangle(0, 0, getHeight(), getWidth());
        margins = new Margins(6, 26, 18, 6);

        this.m_XAxis = new HorizontalAxis(screenRect);
        this.m_YAxis = new VerticalAxis(screenRect);

        minXValue = 20.0;
        maxXValue = 40.0;
        minYValue = -10.0;
        maxYValue = 200.0;

        m_XAxis.setTicks(horizontalTicks);
        m_XAxis.setMargins(margins);
        m_XAxis.setMin(minXValue);
        m_XAxis.setMax(maxXValue);

        m_YAxis.setTicks(verticalTicks);
        m_YAxis.setMargins(margins);
        m_YAxis.setMin(minYValue);
        m_YAxis.setMax(maxYValue);
        m_YAxis.setUnit("km/h");

        m_ChartArea = new ChartArea(screenRect.in(margins), horizontalTicks, verticalTicks);

        m_LineChart = new LineChart(screenRect.in(margins));
        m_LineChart.setMinXValue(minXValue);
        m_LineChart.setMaxXValue(maxXValue);

        m_Legend = new Legend(screenRect.in(margins));
    }

    protected void paint(Graphics g) {
        m_ChartArea.draw(g);
        m_XAxis.draw(g);
        m_YAxis.draw(g);
        m_LineChart.draw(g);
        
        m_Legend.clear();
        Enumeration e = m_LineChart.getSeries();
        while (e.hasMoreElements()) {
            DataSeries ds = (DataSeries)e.nextElement();
            m_Legend.addItem(ds.Name, ds.getColor());
        }
        m_Legend.draw(g);
    }

    private double valueWidth() {
        final double width = maxXValue - minXValue;
        if (width < minWidth)
            return minWidth;

        return width;
    }

    private double valueMean() {
        return (maxXValue + minXValue)/2.0;
    }

    public void setAbsoluteMaxX(double absMax) {
        this.absoluteMaxX = absMax;
    }

    public void setMinMaxX(double min, double max) {
        if (min >= max)
            throw new IllegalArgumentException("min < max required");

        if (min < absoluteMinX) {
            max = max - min + absoluteMinX;
            min = absoluteMinX;
        }

        if (max > absoluteMaxX) {
            max = absoluteMaxX;
        }

        minXValue = min;
        maxXValue = max;

        m_LineChart.setMinXValue(minXValue);
        m_LineChart.setMaxXValue(maxXValue);

        m_XAxis.setMin(minXValue);
        m_XAxis.setMax(maxXValue);
    }

    private void setMinMaxY(double min, double max) {
        minYValue = min;
        maxYValue = max;

        m_YAxis.setMin(min);
        m_YAxis.setMax(max);
    }

    private void setNewMinMax(double width, double mean) {
        setMinMaxX(mean - width/2, mean + width/2);

        //if (autoAdjust)
        m_LineChart.adjustVerticalRange();
        setMinMaxY(m_LineChart.getMinYValue(), m_LineChart.getMaxYValue());
    }

    public void zoomIn() {
        setNewMinMax(valueWidth() * 0.8, valueMean());
    }

    public void zoomOut() {
        setNewMinMax(valueWidth() / 0.8, valueMean());
    }

    public void panLeft() {
        final double w = valueWidth();
        setNewMinMax(w, valueMean()-0.1*w);
    }

    public void panRight() {
        final double w = valueWidth();
        setNewMinMax(w, valueMean()+0.1*w);
    }

    public LineChart lineChart() {
        return m_LineChart;
    }
    
    private final int horizontalTicks = 6;
    private final int verticalTicks = 10;

    private final HorizontalAxis m_XAxis;
    private final VerticalAxis m_YAxis;
    private final ChartArea m_ChartArea;
    private final LineChart m_LineChart;
    private final Legend m_Legend;

    private final Margins margins;

    private double minXValue = 0.0;
    private double maxXValue = 180.0;
    private double minYValue = -10.0;
    private double maxYValue = 200.0;

    private double absoluteMaxX = 1000.0;
    private final double absoluteMinX = 0.0;
    private final double minWidth = 10.0;
}
